package com.hunttown.mes.common.utils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * created by hunttown on 2017/12/4
 */
public class FormatUtils {

    /**
     * 数字千分位符
     *
     * @param text       要格式化的字符串
     * @param isTowPoint 是否保留两位小数
     * @return 格式化结果
     */
    public static String fmtMicrometer(String text, int isTowPoint) {

        DecimalFormat df = null;

        if (isTowPoint == 1) {
            df = new DecimalFormat("###,##0.00");
        } else {
            df = new DecimalFormat("###,##0");
        }

        double number = 0.0;
        try {
            number = Double.parseDouble(text);
        } catch (Exception e) {
            number = 0.0;
        }

        return df.format(number);
    }

    // 保留两位小数 Float
    public static String fmt2point(float f) {
        DecimalFormat df = new DecimalFormat("#.00");
        String res = df.format(f);
        return fmt2PointStartwithZero(res);
    }

    // 保留N位小数 Float
    public static String fmtNPoint(float f, int length) {
        StringBuilder zero = new StringBuilder();
        for (int i = 0; i < length; i++) {
            zero.append("0");
        }

        DecimalFormat df = new DecimalFormat("#");
        if (zero.length() > 0) {
            df = new DecimalFormat("#." + zero);
        }

        String res = df.format(f);
        return fmt2PointStartwithZero(res);
    }

    // 保留两位小数 Double
    public static String fmt2point(double f) {
        DecimalFormat df = new DecimalFormat("#.00");
        String res = df.format(f);
        return fmt2PointStartwithZero(res);
    }

    // 保留两位小数 BigDecimal
    public static String fmt2point(BigDecimal f) {
        DecimalFormat df = new DecimalFormat("#.00");
        String res = df.format(f);
        return fmt2PointStartwithZero(res);
    }

    // 保留两位小数 返回 BigDecimal
    public static BigDecimal fmt2pointDecimal(BigDecimal f) {
        DecimalFormat df = new DecimalFormat("#.00");
        return new BigDecimal(df.format(f));
    }

    // 保留两位小数 返回 Float
    public static Float fmt2pointFloat(BigDecimal f) {
        DecimalFormat df = new DecimalFormat("#.00");
        return Float.valueOf(df.format(f));
    }

    //把 .00结果包装成 0.00
    private static String fmt2PointStartwithZero(String res) {
        if (res.startsWith(".")) {
            res = "0" + res;
        }
        if (res.startsWith("-.")) {
            res = "-0" + res.substring(1);
        }

        return res;
    }

    // 取整 返回 BigDecimal
    public static BigDecimal fmtIntegerDecimal(BigDecimal d) {
        return new BigDecimal(Math.rint(Double.parseDouble(d.toString())));
    }

    // Bigdecimal 保留N位小数
    public static double bigdecimal2Point(BigDecimal d, int len) {
        return d.setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 百分比
     *
     * @param text   double/interger
     * @param nPoint 保留N位小数
     * @return 56.62%
     */
    public static String fmtPercent(String text, int nPoint) {
        float f = Float.parseFloat(text);
        f = f * 100;
        String fmt = fmtNPoint(f, nPoint);

        return fmt + "%";
    }

    public static String fmtPercent(BigDecimal text, int nPoint) {
        if (text == null) {
            return fmtNPoint(0f, nPoint) + "%";
        }

        float f = Float.parseFloat(text.toString());
        f = f * 100;
        String fmt = fmtNPoint(f, nPoint);

        return fmt + "%";
    }

    /**
     * 处理字符串前后逗号 如：",5,6,7," 处理成 "5,6,7"
     *
     * @param fmtstr 需要处理的字符串
     * @return 标准字符串 "5,6,7"
     */
    public static String formatCommas(String fmtstr) {
        if (fmtstr == null || Objects.equals(fmtstr, "")) {
            return "";
        }

        // 替换中文逗号
        fmtstr = fmtstr.replace("，", ",");

        while (fmtstr.substring(0, 1).equals(",")) {
            if (fmtstr.length() == 1 && fmtstr.equals(",")) {
                return "";
            }
            if (fmtstr.length() == 1 && !fmtstr.equals(",")) {
                return fmtstr;
            }

            fmtstr = fmtstr.substring(1, fmtstr.length());
        }

        while (fmtstr.substring(fmtstr.length() - 1).equals(",")) {
            if (fmtstr.length() == 1 && fmtstr.equals(",")) {
                return "";
            }
            if (fmtstr.length() == 1 && !fmtstr.equals(",")) {
                return fmtstr;
            }

            fmtstr = fmtstr.substring(0, fmtstr.length() - 1);
        }

        return fmtstr;
    }

    /**
     * 将字符串 ",5,6,7," 处理成List（Long）
     *
     * @param fmtStr 传入字符串以逗号隔开
     * @return list
     */
    public static List<Long> commaToList_Long(String fmtStr) {
        List<Long> idList = new ArrayList<Long>();

        if (fmtStr == null || Objects.equals(fmtStr, "")) {
            return idList;
        }

        fmtStr = formatCommas(fmtStr);
        String[] ids = fmtStr.split(",");
        for (String item : ids) {
            if (item.equals("on")) {
                continue;
            }
            idList.add(Long.valueOf(item));
        }

        return idList;
    }

    /**
     * 将字符串 ",5,6,7," 处理成List（Int）
     *
     * @param fmtStr 传入字符串以逗号隔开
     * @return list
     */
    public static List<Integer> commaToList_Integer(String fmtStr) {
        List<Integer> idList = new ArrayList<Integer>();

        if (fmtStr == null || Objects.equals(fmtStr, "")) {
            return idList;
        }

        fmtStr = formatCommas(fmtStr);
        String[] ids = fmtStr.split(",");
        for (String item : ids) {
            if (item.equals("on")) {
                continue;
            }
            idList.add(Integer.valueOf(item));
        }

        return idList;
    }

    /**
     * 将字符串处理成List（String）
     *
     * @param fmtStr 传入字符串以逗号隔开
     * @return list
     */
    public static List<String> commaToList_String(String fmtStr) {
        List<String> idList = new ArrayList<String>();

        if (fmtStr == null || Objects.equals(fmtStr, "")) {
            return idList;
        }

        fmtStr = formatCommas(fmtStr);
        String[] ids = fmtStr.split(",");
        for (String item : ids) {
            if (item.equals("on")) {
                continue;
            }
            idList.add(item.trim());
        }

        return idList;
    }

    /**
     * 将字符串处理成List（String）
     *
     * @param fmtStr 传入字符串以空格隔开
     * @return list
     */
    public static List<String> commaToStringList(String fmtStr) {
        List<String> strList = new ArrayList<String>();

        if (fmtStr == null || Objects.equals(fmtStr, "")) {
            return strList;
        }

        fmtStr = fmtStr.trim();
        String[] attr = fmtStr.split(" ");
        for (String item : attr) {
            strList.add(item.trim());
        }

        return strList;
    }

    /**
     * 将List转为String
     *
     * @param list      Integer List
     * @param delimiter 连接符
     * @return list
     */
    public static String integerListCommaToString(List<Integer> list, String delimiter) {
        if (list == null || list.size() == 0) {
            return null;
        }

        String str = "";
        for (Integer item : list) {
            if (Objects.equals(str, "")) {
                str += item;
            } else {
                str += delimiter + item;
            }
        }
        return str;
    }

    //整型相除并输出double
    public static double intToDoubleDivide(int a, int b) {
        double aa = a;
        double bb = b;
        return aa / bb;
    }

    //保留两位小数 Double 含前导0
    public static String fmt2pointWithZero(double f) {
        DecimalFormat df = new DecimalFormat("#.00");
        String result = df.format(f);

        if (result.startsWith(".")) {
            result = "0" + result;
        }
        if (result.startsWith("-.")) {
            result = "-0" + result.substring(1);
        }
        return result;
    }

    //保留n位小数，含前导0
    public static String fmtnpointWithZero(String f, int n) {
        String pattern;
        if (n == 0) {
            pattern = "#";
        } else {
            pattern = "#.";
        }
        for (int i = 0; i < n; i++) {
            pattern += "0";
        }
        DecimalFormat df = new DecimalFormat(pattern);
        double number = 0.0;
        try {
            number = Double.parseDouble(f);
        } catch (Exception e) {
            number = 0.0;
        }
        String result = df.format(number);
        if (result.startsWith(".")) {
            result = "0" + result;
        }
        if (result.startsWith("-.")) {
            result = "-0" + result.substring(1);
        }
        return result;
    }

    //给两个汉字中间加个空格
    public static String formtUsername(String name) {
        if (StringUtils.isBlank(name)) {
            return name;
        }

        if (name.length() == 2) {
            name = name.substring(0, 1) + "&emsp;" + name.substring(1, 2);
        }

        return name;
    }

    /**
     * 转化为IEEE754浮点数
     *
     * @param dataStr 低前高后顺序
     * @return float
     */
    public static float bitsToIEEE754(String dataStr) {
        return Float.intBitsToFloat(Integer.valueOf(dataStr, 16));
    }

    // （整型）十六进制转十进制
    public static int hexToTen(String strHex) {
        if (StringUtils.isBlank(strHex)) {
            return 0;
        }

        BigInteger lngNum = new BigInteger(strHex, 16);
        return lngNum.intValue();
    }

    // （整型）十六进制转十进制（识别正负数）
    public static int hexToTenUnicode(String strHex) {
        if (StringUtils.isBlank(strHex)) {
            return 0;
        }

        BigInteger lngNum = new BigInteger(strHex, 16);
        int res = lngNum.intValue();
        res = ((res & 0x8000) > 0) ? (res - 0x10000) : (res);
        return res;
    }

    // （整型）十六进制转十进制（补码，负数很小的时候需要补码，所以以FF开头）
    public static int hexToTebComplement(String strHex) {
        if (StringUtils.isBlank(strHex)) {
            return 0;
        }
        if (!strHex.toLowerCase().startsWith("ff")) {
            return 0;
        }

        //截取4位
        strHex = strHex.substring(strHex.length() - 4);
        return Integer.valueOf(strHex, 16).shortValue();
    }

    // 十进制转十六进制
    public static String tenToHex(int valueTen) {
        return String.format("%08X", valueTen);
    }

    private static String tenToHex_2dot(int valueTen) {
        return String.format("%02X", valueTen);
    }

    // 十六进制 加法
    public static String hexAdd(String preHex, String nextHex) {
        int pre = hexToTen(preHex);
        int next = hexToTen(nextHex);
        int value = pre + next;
        return tenToHex_2dot(value);
    }

    // 十六进制 减法（返回两位结果）
    public static String hexSub(String preHex, String nextHex) {
        if (StringUtils.isBlank(preHex) || StringUtils.isBlank(nextHex)) {
            return "";
        }

        int pre = hexToTen(preHex);
        int next = hexToTen(nextHex);
        int value = pre - next;
        return tenToHex_2dot(value);
    }

    // 位数不够左边补0
    public static String leftFormatZero(int number) {

        //得到一个NumberFormat的实例
        NumberFormat nf = NumberFormat.getInstance();

        //设置是否使用分组
        nf.setGroupingUsed(false);

        //设置最大整数位数
        nf.setMaximumIntegerDigits(4);

        //设置最小整数位数
        nf.setMinimumIntegerDigits(4);

        return nf.format(number);
    }

    /**
     * 16进制表示的字符串转换为字节数组
     *
     * @param hex 16进制表示的字符串
     * @return byte[] 字节数组
     */
    public static int[] hexStringToIntArray(String hex) {
        int len = hex.length();
        int[] bits = new int[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节
            bits[i / 2] = (int) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return bits;
    }

    /**
     * 字符串转换为16进制字符串
     *
     * @param origin 待转化符串
     * @return 16进制字符串
     */
    public static String stringToHexString(String origin) {
        StringBuilder str = new StringBuilder();

        for (int i = 0; i < origin.length(); i++) {
            int ch = (int) origin.charAt(i);
            String s4 = Integer.toHexString(ch);
            str.append(s4);
        }

        return str.toString();
    }

    /**
     * 16进制字符串转换为字符串
     *
     * @param origin 待转化符串
     * @return 字符串
     */
    public static String hexStringToString(String origin) {
        if (origin == null || origin.equals("")) {
            return null;
        }

        origin = origin.replace(" ", "");
        byte[] baKeyword = new byte[origin.length() / 2];

        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(origin.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {
            origin = new String(baKeyword, "gbk");
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return origin;
    }

    /**
     * 将byte[]数组转换成16进制字符。一个byte生成两个字符，长度对应1:2
     *
     * @param bytes，输入byte[]数组
     * @return 16进制字符
     */
    public static String byte2Hex(byte[] bytes) {
        if (bytes == null) {
            return null;
        }

        StringBuilder builder = new StringBuilder();

        // 遍历byte[]数组，将每个byte数字转换成16进制字符，再拼接起来成字符串
        for (int i = 0; i < bytes.length; i++) {
            // 每个byte转换成16进制字符时，bytes[i] & 0xff如果高位是0，输出将会去掉，所以+0x100(在更高位加1)，再截取后两位字符
            builder.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
        }
        return builder.toString();
    }

    /**
     * 将16进制字符转换成byte[]数组。与byte2Hex功能相反。
     *
     * @param string 16进制字符串
     * @return byte[]数组
     */
    public static byte[] hex2Byte(String string) {
        if (string == null || string.length() < 1) {
            return null;
        }

        // 因为一个byte生成两个字符，长度对应1:2，所以byte[]数组长度是字符串长度一半
        byte[] bytes = new byte[string.length() / 2];

        // 遍历byte[]数组，遍历次数是字符串长度一半
        for (int i = 0; i < string.length() / 2; i++) {
            // 截取没两个字符的前一个，将其转为int数值
            int high = Integer.parseInt(string.substring(i * 2, i * 2 + 1), 16);
            // 截取没两个字符的后一个，将其转为int数值
            int low = Integer.parseInt(string.substring(i * 2 + 1, i * 2 + 2), 16);
            // 高位字符对应的int值*16+低位的int值，强转成byte数值即可
            // 如dd，高位13*16+低位13=221(强转成byte二进制11011101，对应十进制-35)
            bytes[i] = (byte) (high * 16 + low);
        }
        return bytes;
    }

    //十六进制转成byte类型
    public static byte hexToByte(String arg) {
        int val = Integer.valueOf(arg, 16);
        return (byte) (val & 0xff);
    }

    /**
     * BCD码转为10进制串(阿拉伯数据)
     *
     * @param bcdCode BCD码
     * @return 10进制串
     */
    public static String bcd2TenStr(String bcdCode) {
        byte[] bytes = bcdCode.getBytes(StandardCharsets.UTF_8);
        StringBuilder temp = new StringBuilder(bytes.length * 2);
        for (byte aByte : bytes) {
            temp.append((byte) ((aByte & 0xf0) >>> 4));
            temp.append((byte) (aByte & 0x0f));
        }
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString();
    }

    /**
     * 10进制串转为BCD码
     *
     * @param strCode 10进制串
     * @return BCD码
     */
    public static String tenStr2Bcd(String strCode) {
        int len = strCode.length();
        int mod = len % 2;
        if (mod != 0) {
            strCode = "0" + strCode;
            len = strCode.length();
        }

        byte[] abt = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }

        byte[] bbt = new byte[len];
        abt = strCode.getBytes();

        int j, k;
        for (int p = 0; p < strCode.length() / 2; p++) {
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
                j = abt[2 * p] - '0';
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
                j = abt[2 * p] - 'a' + 0x0a;
            } else {
                j = abt[2 * p] - 'A' + 0x0a;
            }
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
                k = abt[2 * p + 1] - '0';
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
                k = abt[2 * p + 1] - 'a' + 0x0a;
            } else {
                k = abt[2 * p + 1] - 'A' + 0x0a;
            }
            int a = (j << 4) + k;
            byte b = (byte) a;
            bbt[p] = b;
        }
        return new String(bbt, StandardCharsets.UTF_8);
    }

    /**
     * 米/秒 转 千米/小时
     * 1 米/秒=3.6 千米/时(千米/小时)
     *
     * @param meter 米/秒
     * @return 千米/小时
     */
    public static String fmtMeToKm(float meter) {
        if (meter <= 0) {
            return "0";
        }

        float km = meter * 3.6f;
        return fmt2point(km);
    }

    public static void main(String[] args) throws Exception {
        //补码  FFFFFE6F
        BigDecimal s = new BigDecimal(Integer.valueOf("FE6F", 16).shortValue());
        BigDecimal ss = new BigDecimal("0.001");
        System.out.println(s.multiply(ss));


        //System.out.println("hex：" + stringToHexString("hex"));
        //System.out.println("str：" + hexStringToString("303131333133303331"));

        /*
        String hex = stringToHexString("101");
        System.out.println("s-h:" + hex);
        System.out.println("h-s:" + hexStringToString(hex));
        */

        /*
        System.out.println(fmtNPoint(2.3f, 3));
        System.out.println(fmtNPoint(2.356f, 3));
        System.out.println(fmtNPoint(2.35633f, 3));
        System.out.println(fmtNPoint(2f, 3));
        System.out.println(fmtNPoint(2.356f, 0));
        System.out.println(fmtNPoint(2.35663f, 3));

        System.out.println(fmtPercent("2.369452", 2));
        System.out.println(fmtPercent("2.3", 0));
        */

        /*
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        */

        /*
        BigDecimal total = new BigDecimal(1.1);
        System.out.println(total.toString());
        System.out.println(fmt2point(Float.parseFloat(total.toString())));
        */

        /*
        System.out.println(hexToTen("FF9B"));
        System.out.println(hexToTenUnicode("FF9B"));
        */
    }
}
